package com.zhangxu.microservice.auth.handler;

import cn.hutool.json.JSONUtil;
import com.zhangxu.microservice.common.exception.BizException;
import com.zhangxu.microservice.common.result.CommonResult;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Optional;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    public static final String IP_HEADER_REAL_IP = "X-Real-IP";
    public static final String IP_HEADER_FORWARDED = "X-Forwarded-For";

    @ExceptionHandler(BizException.class)
    public <T> CommonResult<T> bizException(BizException exception, HttpServletRequest request) {
        printWarnLog(request, exception);
        return CommonResult.error(CommonResult.ResultCode.SYSTEM_ERROR.getCode(), exception.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public <T> CommonResult<T> exception(Exception exception, HttpServletRequest request) {
        printErrorLog(request, exception);
        return CommonResult.error(CommonResult.ResultCode.SYSTEM_ERROR.getCode(), exception.getMessage());
    }

    private void printErrorLog(HttpServletRequest request, Throwable exception) {
        log.error("操作失败, URI:{}, IP: {}, Referer: {}, UA: {}, Param: {}, Cookie: {}", request.getRequestURI(), getIp(request), request.getHeader("Referer"), request.getHeader("User-Agent"), JSONUtil.toJsonStr(request.getParameterMap()), JSONUtil.toJsonStr(request.getCookies()), exception);
    }

    private void printWarnLog(HttpServletRequest request, Throwable exception) {
        log.warn("操作失败, URI:{}, IP: {}, Referer: {}, UA: {}, Param: {}, Cookie: {}", request.getRequestURI(), getIp(request), request.getHeader("Referer"), request.getHeader("User-Agent"), JSONUtil.toJsonStr(request.getParameterMap()), JSONUtil.toJsonStr(request.getCookies()), exception);
    }

    private String getIp(HttpServletRequest request) {
        return Optional.ofNullable(request.getHeader(IP_HEADER_FORWARDED)).orElse(Optional.ofNullable(request.getHeader(IP_HEADER_REAL_IP)).orElse(""));
    }
}